/*************************************************************************
	> File Name: 001.Queue.c
	> Author: Maureen 
	> Mail: Maureen@qq.com 
	> Created Time: 四  9/ 2 20:44:24 2021
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//普通队列，存在假溢出问题


typedef struct Queue {
    int *data;
    int head, tail;
    int capacity;
} Queue;


/*
 * 队列的初始化 
 */
Queue *init(int n) {
    Queue *que = (Queue *)malloc(sizeof(Queue));
    que->data = (int *)malloc(sizeof(int) * n);
    que->head = 0;
    que->tail = 0;
    que->capacity = n;
    return que;
}

/*
 * 返回队首元素
 */
int front(Queue *que) {
    return que->data[que->head];
}

/*
 * 判断队列是否为空
 */
int empty(Queue *que) {
    return que->head == que->tail;
}

/*
 * 入队
 */
int push(Queue *que, int val) {
    if (que == NULL) return -1;
    if (que->tail == que->capacity) { //判断队列是否满了
        return -1;
    }
    que->data[que->tail++] = val;//先入队再更新tail值
    return 0;
}

/*
 * 出队
 */
int pop(Queue *que) {
    if (que == NULL) return -1;
    if (empty(que)) return -1;
    que->head++;
    return 0;
}

/*
 * 队列元素的打印
 */
void output(Queue *que) {
    printf("Queue : [");
    for (int i = que->head, j = 0; i < que->tail; i++, j++) {
        j && printf(", ");
        printf("%d", que->data[i]);
    }
    printf("]\n");
    return ;
}

/*
 * 队列的销毁
 */
void clear(Queue *que) {
    if (que == NULL) return ;
    free(que->data);
    free(que);
    return ;
}

int main() {
    srand(time(0));
    #define max_op 20
    Queue *que = init(max_op);
    for (int i = 0; i < max_op * 2; i++) {
        int val = rand() % 100;
        int op = rand() % 4;
        switch (op) {
            case 0:
            case 1:
            case 2: {
                printf("push %d to the Queue, result = %d\n", val, push(que, val));
            } break;
            case 3: {
                printf("pop %d from the Queue, result = %d\n", front(que), pop(que));
            } break;
        }
        output(que), printf("\n");
    }
    #undef max_op
    clear(que);

    return 0;
}
